// pages/index/index.js
const util = require('../../utils/util.js')
const api = require('../../data/api.js')
const dao = require('../../data/dao.js')

Page({

	/**
	 * 页面的初始数据
	 */
	data: {
		selected_secret_name: null, // 选中的口令名
		selected_secret: null, // 选中的口令
		selected_secret_result: null, // 选中的口令的计算结果
		totp_secret_list: [], // 口令列表

		intervalId: null, // 动态绘制更新口令结果的定时器
		timestamp_adj: null, // 用来矫正时间，使得从12点方向开始绘制进度

		windowWidth: null,
		windowHeight: null,
		secret_list_height: "400rpx",
	},
	// ==============================================
	// 查看口令
	totp_secret_view: function (event) {
		var name = event.currentTarget.dataset.name;
		console.log("totp_secret_view", name);
		util.MyLog.log("跳转查看口令: " + name);
		wx.navigateTo({
			url: '../../pages/secretView/secretView?'
				+ 'name=' + encodeURIComponent(name)
		})
	},
	// 编辑口令
	totp_secret_edit: function (event) {
		var name = event.currentTarget.dataset.name;
		console.log("totp_secret_edit", name);
		util.MyLog.log("跳转编辑口令: " + name);
		wx.navigateTo({
			url: '../../pages/secretEdit/secretEdit?action=edit'
				+ '&name=' + encodeURIComponent(name)
		})
	},
	// 创建口令
	totp_secret_create: function (event) {
		console.log("totp_secret_create");
		util.MyLog.log("跳转创建口令");
		wx.navigateTo({
			url: '../../pages/secretEdit/secretEdit?action=create'
		})
	},
	// 获取口令且显示
	totp_gen_token: function (event) {
		var secret = event.currentTarget.dataset.secret;
		var name = event.currentTarget.dataset.name;
		// 设置选中的口令，结果为空
		this.setData({
			selected_secret_name: name,
			selected_secret: secret,
			selected_secret_result: null,
		});
		util.MyLog.log("获取口令: " + name);
		// 启动定时，计算口令并绘制
		this.startUpdateSelectedSecret();
	},
	// 复制口令值
	totp_token_copy: function (event) {
		//console.log("totp_token_copy", this.data.selected_secret_result);
		if (this.data.selected_secret_result) {
			var val = this.data.selected_secret_result.token;
			wx.setClipboardData({
				data: val,
				success: function (res) {
					wx.showToast({
						title: "复制成功！",
					});
				}
			});
		}
	},
	// 停止显示口令
	stopUpdateSelectedSecret: function () {
		if (this.data.intervalId != null) {
			clearInterval(this.data.intervalId);
			this.setData({ intervalId: null, selected_secret_result: null });
		}
		this.updateTotpToken(null);
	},
	// 启动显示口令
	restartUpdateSelectedSecret: function () {
		this.stopUpdateSelectedSecret();
		this.startUpdateSelectedSecret();
	},
	startUpdateSelectedSecret: function () {
		// 已启动
		if (this.data.intervalId)
			return;
		// 验证
		if (!this.data.selected_secret) {
			this.updateTotpToken(null);
			return;
		}
		// 启动定时计算和绘制口令结果
		//console.log('setInterval...');
		this.computeTimestampAdj();
		var intervalId = setInterval(this.updateSelectedSecret, 100);
		this.setData({
			intervalId: intervalId,
		});
	},
	// 计算adj，作为补偿，使得从12点钟方向开始显示口令
	computeTimestampAdj: function() {
		var timestamp = new Date().getTime() / 1000;
		var timestamp_adj = timestamp % 30;
		if (timestamp_adj > 15) {
			timestamp_adj = 30 - timestamp_adj; // 大于15，补到30，用下一轮的
		} else {
			timestamp_adj = - timestamp_adj; // 不够15，退回到0，用之前的
		}
		timestamp_adj = timestamp_adj * 1000;
		//console.log(timestamp_adj);
		this.setData({ timestamp_adj: timestamp_adj });
	},
	// 定时刷新口令并显示
	updateSelectedSecret: function () {
		//console.log("updateSelectedSecret..");

		var that = this;

		// 验证需要绘制
		if (!that.data.selected_secret) {
			that.stopUpdateSelectedSecret();
			return;
		}

		// 使用旧结果绘制，如果旧结果有效的话。
		var result = that.data.selected_secret_result;
		if (result) {
			// 通过对比当前时间和刷新时间和刷新周期来判断
			var timestamp = new Date().getTime() + this.data.timestamp_adj;
			if (timestamp - result.refresh_time <= result.refresh_interval) {
				that.updateTotpToken(result.token, timestamp, result.refresh_time, result.refresh_interval);
				return;
			}
		} else {
			// 旧结果没效，那应该是重选了另一个口令，或口令删除，需要重计算adj
			this.computeTimestampAdj();
		}

		// 使用新结果绘制
		var timestamp = new Date().getTime() + this.data.timestamp_adj;
		api.totp_gen2(that.data.selected_secret, timestamp).then(function (res) {
			//console.log("获取到令牌，设置令牌", res);
			var result = res.data;
			that.setData({ selected_secret_result: result });
			that.updateTotpToken(result.token, timestamp, result.refresh_time, result.refresh_interval);
		});
	},
	// ==============================================
	// 口令绘制
	updateTotpToken: function (token, timestamp, refresh_time, refresh_interval) {
		this.updateTotpToken2(token, timestamp, refresh_time, refresh_interval);
	},
	updateTotpToken2: function (token, timestamp, refresh_time, refresh_interval) {
		//console.log("updateTotpToken2", result);
		// 大小和圆中心点、圆半径
		var wh = this.data.windowWidth * 400 / 750;
		var cx, cy, cr;
		cx = cy = cr = wh / 2;
		cr = cr - 10;
		
		const context = wx.createCanvasContext('mycanvas');

		// 中间横线
		context.beginPath();
		context.strokeStyle = '#ccc'
		context.lineWidth = 1
		context.moveTo(cx - (cr * 3 / 4), cy);
		context.lineTo(cx + (cr * 3 / 4), cy);
		context.stroke();

		// 显示文字
		{
			var str1 = "000000";
			if (token)
				str1 = String(token);
			var str2 = "- - - - - -";
			var str3 = null;
			if (timestamp && refresh_time && refresh_interval) {
				var sec = parseInt((refresh_interval + refresh_time - timestamp) / 1000) + 1;
				str2 = "剩余 " + sec + " 秒刷新";
				str3 = "长按复制";
			}
			context.fillStyle = '#555'
			context.textAlign = "center";

			context.font = "24px sans-serif";
			context.textBaseline = "bottom";
			context.fillText(str1, cx, cy - 4);

			context.fillStyle = '#777'
			context.font = "14px sans-serif";
			context.textBaseline = "top";
			context.fillText(str2, cx, cy + 6);
			if (str3)
				context.fillText(str3, cx, cy + 24);
			context.stroke()
		}

		// 圆弧进度，灰线
		context.beginPath();
		context.lineWidth = 1
		context.strokeStyle = '#ccc'
		context.shadowBlur = 3;
		context.shadowColor = '#ccc'
		context.arc(cx, cy, cr - 2, 0, 2 * Math.PI);
		context.stroke()

		// 圆弧进度，绿线
		if (timestamp && refresh_time && refresh_interval) {
			var k = (timestamp - refresh_time) / refresh_interval;
			k = Math.PI * 2 * k;
			context.beginPath();
			context.lineWidth = 2
			context.strokeStyle = '#7a7'
			context.shadowBlur = 3;
			context.shadowColor = '#7a7'
			context.translate(cx, cy)
			context.rotate(- Math.PI / 2);
			context.arc(0, 0, cr - 2, 0, k);
			context.stroke()

			// 进度的终点绘制原点
			context.beginPath();
			context.arc(
				Math.cos(k) * (cr - 2),
				Math.sin(k) * (cr - 2),
				3, 0, Math.PI * 2);
			context.fill()
			context.stroke()

			// 纠正旋转和移位
			//context.beginPath();
			//context.rotate(Math.PI / 2);
			//context.translate(-cx, -cy)
			//context.stroke()
		}

		context.draw()
	},

	// ==============================================
	/**
	 * 生命周期函数--监听页面加载
	 */
	onLoad: function (options) {
		var that = this;
		// 获取窗口大小，同时设置口令列表显示区高度
		wx.getSystemInfo({
			success: function (res) {
				var h = "500rpx";
				h = (700 * res.windowHeight / res.windowWidth) * 55 / 100; // 比例
				h += "rpx";
				that.setData({
					windowWidth: res.windowWidth,
					windowHeight: res.windowHeight,
					secret_list_height: h,
				});
			}
		});
	},

	/**
	 * 生命周期函数--监听页面初次渲染完成
	 */
	onReady: function () {

	},

	/**
	 * 生命周期函数--监听页面显示
	 */
	onShow: function () {
		var that = this;
		// 加载secret列表
		var list = dao.totp_config.getSecretList();
		// 设置过期状态
		var time = new Date().getTime();
		var day = 1000 * 60 * 60 * 24;
		list.forEach(function (e) {
			e.fromNowStr = util.fromNowString(e.time);
			if (!e.ttl)
				e.ttl = 30;
			if (time - e.time > e.ttl * day) {
				e.message = "口令秘钥过期！";
			} else {
				e.message = "";
			}
			// 同时看是否要更新当前所选中的secret
			/*
			if (!that.data.selected_secret_name) {
				that.setData({
					selected_secret_name: e.name,
					selected_secret: e.secret,
					selected_secret_result: null,
				});
				return;
			}*/
			
			if (e.name == that.data.selected_secret_name) {
				if (e.secret != that.data.selected_secret) {
					that.setData({
						selected_secret: e.secret,
						selected_secret_result: null,
					});
				}
			}
		});

		//
		this.setData({
			totp_secret_list: list
		});

		// 显示默认的secret结果
		this.startUpdateSelectedSecret();
	},

	/**
	 * 生命周期函数--监听页面隐藏
	 */
	onHide: function () {
		this.stopUpdateSelectedSecret();
	},

	/**
	 * 生命周期函数--监听页面卸载
	 */
	onUnload: function () {
		this.stopUpdateSelectedSecret();
	},

	/**
	 * 页面相关事件处理函数--监听用户下拉动作
	 */
	onPullDownRefresh: function () {

	},

	/**
	 * 页面上拉触底事件的处理函数
	 */
	onReachBottom: function () {

	},

	/**
	 * 用户点击右上角分享
	 */
	onShareAppMessage: function (options) {
		return {
			title: '动态口令',
			path: '/pages/index/index',
			imageUrl: '/image/share.png', // 使用专门的分享图片，默认截图会截取用户的口令
		}
	},
})